From: Ell Date: Sat, 4 Aug 2018 06:18:37 +0000 (-0400) Subject: babl-cache: store reference fishes in the cache X-Git-Tag: archive/raspbian/1%0.1.106-3+rpi1^2~15^2~15^2~1 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=c21c3f2d671b61dbbb223c444d68b02c06d3df14;p=babl.git babl-cache: store reference fishes in the cache When we only have a reference fish for a given conversion, and not a path fish, store a corresponding entry in the cache, marked by a "[reference]" tag in the fish's attributes line, and containing no conversion list. When reloading the cache, make sure a reference fish is created for the conversion without trying to construct a path fish, so that we don't waste time trying to search for a conversion path. Note that we still show a "missing fast path" warning, even for cached reference fishes. --- diff --git a/babl/babl-cache.c b/babl/babl-cache.c index e85216e..48e359c 100644 --- a/babl/babl-cache.c +++ b/babl/babl-cache.c @@ -108,8 +108,11 @@ static char * babl_fish_serialize (Babl *fish, char *dest, int n) { char *d = dest; - if (fish->class_type != BABL_FISH_PATH) + if (fish->class_type != BABL_FISH && + fish->class_type != BABL_FISH_PATH) + { return NULL; + } snprintf (d, n, "%s\n%s\n", babl_get_name (fish->fish.source), @@ -119,20 +122,32 @@ babl_fish_serialize (Babl *fish, char *dest, int n) snprintf (d, n, "\tpixels=%li", fish->fish.pixels); n -= strlen (d);d += strlen (d); - snprintf (d, n, " cost=%d", (int)fish->fish_path.cost); - n -= strlen (d);d += strlen (d); + if (fish->class_type == BABL_FISH_PATH) + { + snprintf (d, n, " cost=%d", (int)fish->fish_path.cost); + n -= strlen (d);d += strlen (d); + } snprintf (d, n, " error=%f", fish->fish.error); n -= strlen (d);d += strlen (d); + if (fish->class_type == BABL_FISH) + { + snprintf (d, n, " [reference]"); + n -= strlen (d);d += strlen (d); + } + snprintf (d, n, "\n"); n -= strlen (d);d += strlen (d); - for (int i = 0; i < fish->fish_path.conversion_list->count; i++) + if (fish->class_type == BABL_FISH_PATH) { - snprintf (d, n, "\t%s\n", - babl_get_name(fish->fish_path.conversion_list->items[i] )); - n -= strlen (d);d += strlen (d); + for (int i = 0; i < fish->fish_path.conversion_list->count; i++) + { + snprintf (d, n, "\t%s\n", + babl_get_name(fish->fish_path.conversion_list->items[i] )); + n -= strlen (d);d += strlen (d); + } } return dest; @@ -278,19 +293,45 @@ void babl_init_db (void) return; } - babl = babl_calloc (1, sizeof (BablFishPath) + - strlen (name) + 1); - babl_set_destructor (babl, _babl_fish_path_destroy); - - babl->class_type = BABL_FISH_PATH; - babl->instance.id = babl_fish_get_id (from_format, to_format); - babl->instance.name = ((char *) babl) + sizeof (BablFishPath); - strcpy (babl->instance.name, name); - babl->fish.source = from_format; - babl->fish.destination = to_format; - babl->fish_path.conversion_list = babl_list_init_with_size (10); - _babl_fish_prepare_bpp (babl); - _babl_fish_rig_dispatch (babl); + if (strstr (token, "[reference]")) + { + /* there isn't a suitable path for requested formats, + * let's create a dummy BABL_FISH instance and insert + * it into the fish database to indicate that such path + * does not exist. + */ + const char *name = "X"; /* name does not matter */ + babl = babl_calloc (1, sizeof (BablFish) + strlen (name) + 1); + + babl->class_type = BABL_FISH; + babl->instance.id = babl_fish_get_id (from_format, + to_format); + babl->instance.name = ((char *) babl) + sizeof (BablFish); + strcpy (babl->instance.name, name); + babl->fish.source = from_format; + babl->fish.destination = to_format; + babl->fish.data = (void*) 1; /* signals babl_fish() to + * show a "missing fash path" + * warning upon the first + * lookup + */ + } + else + { + babl = babl_calloc (1, sizeof (BablFishPath) + + strlen (name) + 1); + babl_set_destructor (babl, _babl_fish_path_destroy); + + babl->class_type = BABL_FISH_PATH; + babl->instance.id = babl_fish_get_id (from_format, to_format); + babl->instance.name = ((char *) babl) + sizeof (BablFishPath); + strcpy (babl->instance.name, name); + babl->fish.source = from_format; + babl->fish.destination = to_format; + babl->fish_path.conversion_list = babl_list_init_with_size (10); + _babl_fish_prepare_bpp (babl); + _babl_fish_rig_dispatch (babl); + } token2 = strtok_r (&token[1], seps2, &tokp2); while( token2 != NULL ) @@ -301,7 +342,8 @@ void babl_init_db (void) } else if (!strncmp (token2, "cost=", 5)) { - babl->fish_path.cost = babl_parse_double (token2 + 5); + if (babl->class_type == BABL_FISH_PATH) + babl->fish_path.cost = babl_parse_double (token2 + 5); } else if (!strncmp (token2, "pixels=", 7)) { @@ -310,7 +352,7 @@ void babl_init_db (void) token2 = strtok_r (NULL, seps2, &tokp2); } } - else if (to_format && babl) + else if (to_format && babl && babl->class_type == BABL_FISH_PATH) { Babl *conv = (void*)babl_db_find(babl_conversion_db(), &token[1]); if (!conv) diff --git a/babl/babl-fish-path.c b/babl/babl-fish-path.c index 30c4a68..2e87268 100644 --- a/babl/babl-fish-path.c +++ b/babl/babl-fish-path.c @@ -464,6 +464,34 @@ _babl_fish_prepare_bpp (Babl *babl) } } +void +_babl_fish_missing_fast_path_warning (const Babl *source, + const Babl *destination) +{ +#ifndef BABL_UNSTABLE + if (debug_conversions) +#endif + { + static int warnings = 0; + + if (_babl_legal_error() <= 0.0000000001) + return; + + if (warnings++ == 0) + fprintf (stderr, +"Missing fast-path babl conversion detected, Implementing missing babl fast paths\n" +"accelerates GEGL, GIMP and other software using babl, warnings are printed on\n" +"first occurance of formats used where a conversion has to be synthesized\n" +"programmatically by babl based on format description\n" +"\n"); + + fprintf (stderr, "*WARNING* missing babl fast path(s): \"%s\" to \"%s\"\n", + babl_get_name (source), + babl_get_name (destination)); + + } +} + static Babl * babl_fish_path2 (const Babl *source, @@ -599,28 +627,8 @@ babl_fish_path2 (const Babl *source, babl_free (babl); babl_mutex_unlock (babl_format_mutex); -#ifndef BABL_UNSTABLE - if (debug_conversions) -#endif - { - static int warnings = 0; - - if (_babl_legal_error() <= 0.0000000001) - return NULL; + _babl_fish_missing_fast_path_warning (source, destination); - if (warnings++ == 0) - fprintf (stderr, -"Missing fast-path babl conversion detected, Implementing missing babl fast paths\n" -"accelerates GEGL, GIMP and other software using babl, warnings are printed on\n" -"first occurance of formats used where a conversion has to be synthesized\n" -"programmatically by babl based on format description\n" -"\n"); - - fprintf (stderr, "*WARNING* missing babl fast path(s): \"%s\" to \"%s\"\n", - babl_get_name (source), - babl_get_name (destination)); - - } return NULL; } diff --git a/babl/babl-fish.c b/babl/babl-fish.c index 8d31e1b..a1baa50 100644 --- a/babl/babl-fish.c +++ b/babl/babl-fish.c @@ -290,6 +290,16 @@ babl_fish (const void *source, } #endif } + else if (ffish.fish_fish->fish.data) + { + /* the dummy fish was created by the cache, and we need to manually + * show a "missing fast path" warning for it on the first lookup. + */ + _babl_fish_missing_fast_path_warning (ffish.fish_fish->fish.source, + ffish.fish_fish->fish.destination); + + ffish.fish_fish->fish.data = NULL; + } } if (ffish.fish_ref) diff --git a/babl/babl-internal.h b/babl/babl-internal.h index a6f1196..0f8a07c 100644 --- a/babl/babl-internal.h +++ b/babl/babl-internal.h @@ -427,6 +427,8 @@ babl_conversion_process (const Babl *babl, conversion->dispatch (babl, source, destination, n, conversion->data); } +void _babl_fish_missing_fast_path_warning (const Babl *source, + const Babl *destination); void _babl_fish_rig_dispatch (Babl *babl); void _babl_fish_prepare_bpp (Babl *babl);